home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1994 / 12 / 02 / envoy-kurs / remoteexecute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-01  |  7.1 KB  |  229 lines

  1. /*
  2.  *  RemoteExecute
  3.  *
  4.  *  Führt eine Befehlszeile in einer Shell auf dem angegebenen Rechner aus.
  5.  *  Außerdem kann die Ausgabedatei angegeben werden.
  6.  *
  7.  *  Template: HOSTNAME/A,COMMAND/A,OUTPUT/K
  8.  *  Beispiel: RemoteExecute Amiga1 "dir c:" "ram:ausgabe"
  9.  *
  10.  *  Diese Version benutzt den GPServer.
  11.  */
  12.  
  13. #define VERSION     "1.0"
  14. #define DATE        "12.9.94"
  15. #define PROGNAME    "RemoteExecute"
  16.  
  17. /*
  18.  *  Include-Dateien
  19.  */
  20. #include <stdlib.h>
  21. #define USE_BUILTIN_MATH
  22. #include <string.h>
  23.  
  24. #include <envoy/envoy.h>
  25. #include <envoy/errors.h>
  26. #include <exec/memory.h>
  27.  
  28. #include <clib/dos_protos.h>
  29. #include <pragmas/dos_pragmas.h>
  30. #include <clib/exec_protos.h>
  31. #include <pragmas/exec_sysbase_pragmas.h>
  32. #include <clib/nipc_protos.h>
  33. #include <pragmas/nipc_pragmas.h>
  34.  
  35. #include "GPServer.h"
  36.  
  37. /*
  38.  *  globale Datan
  39.  */
  40.  
  41. /* libraries */
  42. extern struct Library *DOSBase;
  43. extern struct Library *SysBase;
  44. static struct Library *NIPCBase;
  45.  
  46. /* version string */
  47. static const char version[] = "\0$VER: " PROGNAME " " VERSION " (" DATE ")";
  48.  
  49. /* Daten & Definitionen für die Parameter */
  50. #define TEMPLATE "HOSTNAME/A,COMMAND/A,OUTPUT/K"
  51. #define OPTN_HOSTNAME   0
  52. #define OPTN_COMMAND    1
  53. #define OPTN_OUTPUT     2
  54. #define OPTN_COUNT      3
  55. static long options[OPTN_COUNT];
  56. #define HOSTNAME    ((unsigned char *)options[OPTN_HOSTNAME])
  57. #define COMMAND     ((unsigned char *)options[OPTN_COMMAND])
  58. #define OUTPUT      ((unsigned char *)options[OPTN_OUTPUT])
  59.  
  60. /*
  61.  *  Prototypen für Funktionen in dieser Datei
  62.  */
  63. static ULONG remoteexecute(void);
  64. static BOOL makedatapacket(struct Transaction *ta);
  65.  
  66. void main()
  67. {
  68.     struct RDArgs *args;
  69.     ULONG rc = RETURN_OK;
  70.  
  71.     if (SysBase->lib_Version < 37) exit(RETURN_ERROR); /* unter Kick 2.04 geht nichts! */
  72.  
  73.     if (NIPCBase = OpenLibrary("nipc.library", 39))
  74.     {
  75.         /* Parameter auswerten */
  76.         if (args = ReadArgs(TEMPLATE, options, NULL))
  77.         {
  78.             rc = remoteexecute();
  79.             FreeArgs(args);
  80.         }
  81.         else
  82.         {
  83.             /* Fehler bei den Parametern! */
  84.             PrintFault(IoErr(), NULL);
  85.             rc = RETURN_WARN;
  86.         }
  87.  
  88.         CloseLibrary(NIPCBase);
  89.     }
  90.     else PutStr("Kann nipc.library V39 oder neuer nicht öffnen!\n");
  91.  
  92.     exit(rc);
  93. }
  94.  
  95. static ULONG remoteexecute(void)
  96. {
  97.     struct Entity *ausgangs_entity;
  98.     struct Entity *ziel_entity;
  99.     struct Transaction *ta;
  100.     struct Transaction *rta;
  101.     ULONG entitysigbit;
  102.     ULONG error = ENVOYERR_NOERROR;
  103.     ULONG rc = RETURN_ERROR;
  104.     ULONG sigs;
  105.     BOOL quit = FALSE;
  106.  
  107.     /*  Private Entity anlegen. Dabei lassen wir für die Entity gleich ein
  108.      *  SignalBit belegen. Dieses wird in entitysignal abgelegt.
  109.      */
  110.     if (ausgangs_entity = CreateEntity(ENT_AllocSignal, (ULONG)&entitysigbit, TAG_END))
  111.     {
  112.         /*  Kommunikationspfad errichten */
  113.         if (ziel_entity = FindEntity(HOSTNAME, "GPServer", ausgangs_entity, &error))
  114.         {
  115.             /*  Nun allozieren wir die Transaction */
  116.             if (ta = AllocTransaction(TAG_END))
  117.             {
  118.                 /*  Das Datenpaket für die Anfrage schnüren ... */
  119.                 if (makedatapacket(ta))
  120.                 {
  121.                     /*  Die Transaction losschicken ... */
  122.                     ta->trans_Command = TACMD_CMDLINE;
  123.                     BeginTransaction(ziel_entity, ausgangs_entity, ta);
  124.  
  125.                     /*  Nun warten wir auf die Antwort ... */
  126.                     while (!quit)
  127.                     {
  128.                         sigs = Wait((1 << entitysigbit) | SIGBREAKF_CTRL_C);
  129.  
  130.                         if (sigs & (1 << entitysigbit))
  131.                         {
  132.                             /*  Bei unserer Entity ist was angekommen ... */
  133.                             while (rta = GetTransaction(ausgangs_entity))
  134.                             {
  135.                                 if (rta->trans_Type == TYPE_RESPONSE)
  136.                                 {
  137.                                     /* Unsere Transaction ist zurück ... */
  138.                                     quit = TRUE;
  139.                                 }
  140.                                 else
  141.                                 {
  142.                                     /* Das ist nicht unsere Transaction,
  143.                                      * die wir losgeschickt haben; zur
  144.                                      * Sicherheit schicken wie sie zurück
  145.                                      * Dieser Fall darf eigentlich nie auf-
  146.                                      * treten.
  147.                                      */
  148.                                     ReplyTransaction(rta);
  149.                                 }
  150.                             }
  151.                         }
  152.  
  153.                         if (sigs & SIGBREAKF_CTRL_C)
  154.                         {
  155.                             /* Bei CTRL-C sollen wir abbrechen:
  156.                              * dazu müsen wir die Transaction erst abbrechen.
  157.                              */
  158.                             AbortTransaction(ta);
  159.                             WaitTransaction(ta);
  160.                             quit = TRUE;
  161.                         }
  162.                     }
  163.  
  164.                     /* Ist ein Fehler aufgetreten? */
  165.                     if (ta->trans_Error == ENVOYERR_NOERROR)
  166.                     {
  167.                         rc = RETURN_OK;
  168.                     }
  169.                     else
  170.                     {
  171.                         Printf("Envoy-Fehler %lu!\n", ta->trans_Error);
  172.                     }
  173.  
  174.                     /* Datenbereich wieder freigeben */
  175.                     FreeMem(ta->trans_RequestData, ta->trans_ReqDataLength);
  176.                 }
  177.                 /* Transaction freigeben */
  178.                 FreeTransaction(ta);
  179.             }
  180.             /*  Kommunikationspfad freigeben */
  181.             LoseEntity(ziel_entity);
  182.         }
  183.         else
  184.         {
  185.             Printf("GPServer auf Rechner '%s' nicht erreichbar:\n", HOSTNAME);
  186.             Printf("Envoy-Fehler %lu\n", error);
  187.         }
  188.  
  189.         DeleteEntity(ausgangs_entity);
  190.     }
  191.     else PutStr("Kann Entity nicht erzeugen!\n");
  192.  
  193.     return(rc);
  194. }
  195.  
  196. static BOOL makedatapacket(struct Transaction *ta)
  197. {
  198.     /*  Diese Funktion erstellt aus den Kommandozeilenparametern,
  199.      *  die uns der Benutzer angegeben hat, ein Datenpaket, wie es
  200.      *  der Server versteht.
  201.      */
  202.     ULONG datalen;
  203.     unsigned char *data;
  204.  
  205.     /*  Wieviel Bytes an Daten wollen wir an den Server schicken? */
  206.     datalen = strlen(COMMAND) + 2;
  207.     if (OUTPUT) datalen = datalen + strlen(OUTPUT);
  208.  
  209.     if (data = AllocMem(datalen, MEMF_ANY))
  210.     {
  211.         ta->trans_RequestData = data;
  212.         ta->trans_ReqDataLength = datalen;
  213.         ta->trans_ReqDataActual = datalen;
  214.  
  215.         /*  Nun müssen wir die Daten noch in der richtigen Form in den
  216.          *  allozierten Speicher kopieren:
  217.          *  Der GPServer erwartet zuerst den COMMAND-String,
  218.          *  dann den OUTPUT-String; beide Strings sind Null-terminiert;
  219.          */
  220.         strcpy(data, COMMAND);              /* Kommando kopieren    */
  221.         data += strlen(data) + 1;           /* Zeiger vor           */
  222.         if (OUTPUT) strcpy(data, OUTPUT);   /* Output kopieren oder */
  223.         else *data = '\0';                  /* noch ein Nullbyte    */
  224.  
  225.         return(TRUE);
  226.     }
  227.     return(FALSE);
  228. }
  229.